using System.Collections.Generic;
using WCell.Constants.Items;
using WCell.Constants.Looting;
using WCell.RealmServer.Items;
using WCell.Util.Data;
using System.Collections;

namespace WCell.RealmServer.Looting
{
	[DataHolder(Inherit = true)]
	public class GOLootItemEntry : LootItemEntry
	{
	}

	[DataHolder(Inherit = true)]
	public class ItemLootItemEntry : LootItemEntry
	{
		public static IEnumerable<ItemLootItemEntry> GetAllDataHolders()
		{
			var all = new List<ItemLootItemEntry>(20000);
			AddItems(LootEntryType.Item, all);
			AddItems(LootEntryType.Disenchanting, all);
			AddItems(LootEntryType.Prospecting, all);
			AddItems(LootEntryType.Milling, all);
			return all;
		}
	}

	[DataHolder(Inherit = true)]
	public class NPCLootItemEntry : LootItemEntry
	{
		public static IEnumerable<NPCLootItemEntry> GetAllDataHolders()
		{
			var all = new List<NPCLootItemEntry>(500000);
			AddItems(LootEntryType.NPCCorpse, all);
			AddItems(LootEntryType.Skinning, all);
			AddItems(LootEntryType.PickPocketing, all);
			return all;
		}
	}

	[DataHolder(Inherit = true)]
	public class FishingLootItemEntry : LootItemEntry
	{
	}

	public abstract class LootItemEntry : IDataHolder
	{
		public LootEntryType LootType;
		public uint EntryId;
		public ItemId ItemId;
		public uint GroupId;
		public uint MinAmount, MaxAmount;
		public int MinAmountOrRef;
		public bool IsFFA;
		public uint ReferedEntryId;

		/// <summary>
		/// A value between 0 and 100 to indicate the chance of this Entry to drop
		/// </summary>
		public float DropChance;
		/// <summary>
		/// A value between 0 and 100 to indicate the chance of this Entry to drop in heroic mode
		/// </summary>
		public float HeroicDropChance;

		public ItemTemplate ItemTemplate
		{
			get
			{
				return ItemMgr.GetTemplate(ItemId);
			}
		}

		public object GetId()
		{
			return EntryId;
		}

		public void FinalizeDataHolder()
		{
			if (MinAmountOrRef < 0)
			{
				ReferedEntryId = (uint)(-MinAmountOrRef);
			}
			else
			{
				MinAmount = (uint)MinAmountOrRef;
			}

			if (MinAmount < 1)
			{
				MinAmount = 1;
			}

			if (MinAmount > MaxAmount)
			{
				MaxAmount = MinAmount;
			}

			if (DropChance < 0)
			{
				DropChance = -DropChance;
			}

			if (HeroicDropChance == 0)
			{
				HeroicDropChance = DropChance;
			}

			LootMgr.AddEntry(this);
		}

		protected static void AddItems<T>(LootEntryType t, List<T> all)
			where T : LootItemEntry
		{
			var entries = LootMgr.GetEntries(t);
			foreach (var list in entries)
			{
				if (list != null)
				{
					foreach (var entry in list)
					{
						all.Add((T)entry);
					}
				}
			}
		}

		public override string ToString()
		{
			return ItemTemplate + " (" + DropChance + "%)";
		}
	}
}
